package adapletplugin.editors.pages;

import objects.MappingFile;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;

import adapletplugin.dialogs.NewItemDialog;
import adapletplugin.editors.MapFileEditor;
import adapletplugin.editors.input.MapFileEditorInput;

public class MapFileHeaderPage extends FormPage
{
	private MappingFile fMap;
	private ScrolledForm fForm;
	private FormToolkit fToolkit;
	private MapFileEditor fEditor;

	private Text fFileNameText;
	private Text fCommentsText;
	private Text fFieldDelimiterText;
	private Text fRecordDelimiterText;

	private Combo fModeCombo;
	private Text fSchemaText;

	private Text fMaxNotFoundText;
	private Text fTagDBPathText;
	private Text fTagAdminText;
	private Text fLicenseKeyText;

	private TableViewer fAdditionalItemsViewer;
	private Button fNewItemButton;

	public MapFileHeaderPage(FormEditor editor)
	{
		super(editor, "mapfile.header", "Header");

		fMap = ((MapFileEditorInput) editor.getEditorInput()).getMapFile();
		fEditor = (MapFileEditor) editor;
	}

	@Override
	protected void createFormContent(IManagedForm managedForm)
	{
		fForm = managedForm.getForm();
		fForm.setText("Header Information");

		fToolkit = managedForm.getToolkit();

		Composite body = fForm.getBody();
		body.setLayout(new GridLayout(1, true));

		Composite row = fToolkit.createComposite(body);
		row.setLayout(new GridLayout(2, false));
		row.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

		fToolkit.createLabel(row, "Map File Name:");
		fFileNameText = fToolkit.createText(row, "", SWT.READ_ONLY | SWT.BORDER);
		fFileNameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fFileNameText.addModifyListener(createModifyListener_FileName());

		fToolkit.createLabel(row, "Adaplet Mode:");
		fModeCombo = new Combo(row, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER);
		fModeCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fModeCombo.add("readonly");
		fModeCombo.add("readwrite");
		fModeCombo.add("migrate");
		fModeCombo.add("extend");
		fModeCombo.select(0);
		fModeCombo.addModifyListener(createModifyListener_Mode());

		fToolkit.createLabel(row, "Schema:");
		fSchemaText = fToolkit.createText(row, "", SWT.BORDER);
		fSchemaText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fSchemaText.addModifyListener(createModifyListener_Schema());

		fToolkit.createLabel(row, "Export Field Delimiter:");
		fFieldDelimiterText = fToolkit.createText(row, "", SWT.BORDER);
		fFieldDelimiterText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fFieldDelimiterText.addModifyListener(createModifyListener_FieldDelim());

		fToolkit.createLabel(row, "Export Record Delimiter:");
		fRecordDelimiterText = fToolkit.createText(row, "", SWT.BORDER);
		fRecordDelimiterText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fRecordDelimiterText.addModifyListener(createModifyListener_RecordDelim());

		fToolkit.createLabel(row, "Export TagDB Path:");
		fTagDBPathText = fToolkit.createText(row, "", SWT.BORDER);
		fTagDBPathText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fTagDBPathText.addModifyListener(createModifyListener_TagDB());

		fToolkit.createLabel(row, "Export Admin TagDB Path:");
		fTagAdminText = fToolkit.createText(row, "", SWT.BORDER);
		fTagAdminText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fTagAdminText.addModifyListener(createModifyListener_TagAdmin());

		fToolkit.createLabel(row, "Max Not Found Report:");
		fMaxNotFoundText = fToolkit.createText(row, "", SWT.BORDER);
		fMaxNotFoundText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fMaxNotFoundText.addModifyListener(createModifyListener_MaxNotFound());

		fToolkit.createLabel(row, "License Key:");
		fLicenseKeyText = fToolkit.createText(row, "", SWT.BORDER);
		fLicenseKeyText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fLicenseKeyText.addModifyListener(createModifyListener_License());

		fToolkit.createLabel(row, "Add any additional configuration items here:");
		fNewItemButton = fToolkit.createButton(row, "Add Item", SWT.PUSH);
		fNewItemButton.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false, false));
		fNewItemButton.addSelectionListener(createNewItemListener());

		fAdditionalItemsViewer = new TableViewer(body, SWT.BORDER | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION);
		fAdditionalItemsViewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		fAdditionalItemsViewer.setContentProvider(new AdditionalItemContentProvider());
		fAdditionalItemsViewer.setLabelProvider(new AdditionalItemsLabelProvider());
		fAdditionalItemsViewer.getTable().setHeaderVisible(true);

		TableColumn col = new TableColumn(fAdditionalItemsViewer.getTable(), SWT.LEFT);
		col.setText("Item Name");
		col.setWidth(100);
		col.setMoveable(false);
		col.setResizable(true);

		col = new TableColumn(fAdditionalItemsViewer.getTable(), SWT.RIGHT);
		col.setText("Value");
		col.setWidth(100);
		col.setMoveable(false);
		col.setResizable(true);

		fAdditionalItemsViewer.setInput(fMap);

		fToolkit.createLabel(body,
				"Use this area to enter any comments that you wish to appear at the head of your mapping file:");
		fCommentsText = fToolkit.createText(body, "", SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
		fCommentsText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		fCommentsText.addModifyListener(createModifyListener_Comments());

		updateData();
	}

	private SelectionListener createNewItemListener()
	{
		return new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e)
			{

				Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();

				NewItemDialog dialog = new NewItemDialog(shell);

				dialog.create();
				dialog.open();

				if (dialog.getReturnCode() == Window.OK)
				{
					fMap.addAdditionalItem(dialog.getItem(), dialog.getValue());

					fAdditionalItemsViewer.refresh();

					fEditor.refresh();
				}
			}
		};
	}

	private ModifyListener createModifyListener_Schema()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				fMap.setSchema(fSchemaText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_Mode()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				fMap.setMode(fModeCombo.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_Comments()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				fMap.setComments(fCommentsText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_License()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				fMap.setLicense(fLicenseKeyText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_MaxNotFound()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				fMap.setMaxNotFound(fMaxNotFoundText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_TagAdmin()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				fMap.setTagAdmin(fTagAdminText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_TagDB()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				fMap.setTagDB(fTagDBPathText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_RecordDelim()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				fMap.setRecordDelimiter(fRecordDelimiterText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_FieldDelim()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				fMap.setFieldDelimiter(fFieldDelimiterText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_FileName()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				fMap.setMapFileName(fFileNameText.getText());
				fEditor.refresh();
			}
		};
	}

	private void updateData()
	{
		fFileNameText.setText(fMap.getMapFileName());
		fCommentsText.setText(fMap.getComments());
		fFieldDelimiterText.setText(fMap.getFieldDelimiter());
		fRecordDelimiterText.setText(fMap.getRecordDelimiter());
		fModeCombo.setText(fMap.getMode());
		fSchemaText.setText(fMap.getSchema());
		fMaxNotFoundText.setText(fMap.getMaxNotFound());
		fTagAdminText.setText(fMap.getTagAdmin());
		fTagDBPathText.setText(fMap.getTagDB());
		fLicenseKeyText.setText(fMap.getLicense());

	}

	private class AdditionalItemContentProvider implements IStructuredContentProvider
	{

		@Override
		public void dispose()
		{

		}

		@Override
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
		{

		}

		@Override
		public Object[] getElements(Object inputElement)
		{
			MappingFile map = (MappingFile) inputElement;

			return map.getAdditionalItemNames();
		}

	}

	private class AdditionalItemsLabelProvider extends LabelProvider implements ITableLabelProvider
	{

		@Override
		public Image getColumnImage(Object element, int columnIndex)
		{
			return null;
		}

		@Override
		public String getColumnText(Object element, int columnIndex)
		{
			if (columnIndex == 0)
			{
				return (String) element;
			}
			else if (columnIndex == 1)
			{
				return fMap.getAdditionalItemValue((String) element);
			}
			else
			{
				return "Invalid Column";
			}
		}

	}

}
